/**
 * @file ngserver.h
 * @author Suk Robert Koh (srkoh87z@gmail.com)
 *
 * @brief Abstract type of server which gets extended
 */

#ifndef NGSERVER_H_
#define NGSERVER_H_

#include "nguser.h"
#include "../common/ngnetwork.h"
#include "../common/message/ngmessage.h"
#include "../common/message/ngmessagequeue.h"
#include "../common/message/ngmessagecoder.h"
#include "../common/message/ngdefaultmessagecoder.h"
#include "../common/utility/nglogger.h"
#include "../common/utility/ngutils.h"
#include "../common/ngproperties.h"
#include "../common/ngtypes.h"

class NGUser;

/**
 * @class	NGServer	Abstract type of server which gets extended
 */
class NGServer
{
public:
	virtual BOOL sendMessage(NGMessage *msg, DWORD userId);
	virtual BOOL sendMessageAll(NGMessage *msg);
	virtual BOOL sendMessageAll(NGMessage *msg, DWORD excludeUserId);

	void setMessageCoder(NGMessageCoder *_messageCoder);

	int getQueueSize();
	NGMessage *getFirstMessage();

protected:
	NGServer(int _maxUser);
	virtual ~NGServer();

	virtual BOOL process(void) = 0;
	virtual BOOL handleRecv(int arrayPosition) = 0;
	virtual BOOL handleSend(int arrayPosition) = 0;

	NGUser *getEmptyUserSpace(void);
	NGUser *getUser(DWORD userId);
	NGUser *getUser(SOCKET socket);
	BOOL removeUser(DWORD userId);

	NGMessageCoder *messageCoder;								/** Message coder object */

	SOCKET serverSocket;										/** Socket descriptor */
	DWORD currentUserId;										/** Holds the user id to assign to new user */
	int maxFd;													/** For select() */
	int maxUser;												/** Maximum number of users allowed to connect */

	NGUser **users;												/** Holds list of user objects */

	NGMessageQueue *messageQueue;								/** Message queue */
};

#endif /* NGSERVER_H_ */
